<?php

/**
 * 公共函数
 */

use CbjCode\General\Common\Date;
use CbjCode\General\Common\Random;

include_once __DIR__.'/Helps/Response.php';

if (!function_exists('check_image_domain')) {
    /**
     * 图片资源路径域名补全函数
     * @param string|array $image 图片路径
     * @param bool $type 类型:false=string|true=array
     * @param string $rule 分割规则
     * @param string $http 协议
     * @return array|mixed|string
     */
    function check_image_domain(string $image = "", bool $type = false, string $rule = ",", string $http="http")
    {

        if ($image) {
            if ($type){
                if (is_array($image)){
                    foreach ($image as $k=>$v){
                        $image[$k] = check_image_domain($v,false,$rule,$http);
                    }
                }elseif (is_string($image)){
                    $rule = $rule?$rule:",";
                    $image = check_image_domain(explode($rule,$image),$type,$rule,$http);
                }
            }else{
                if (strpos($image, $http) === false) {
                    $image = request()->getSchemeAndHttpHost(). $image;
                }
            }
        }
        return $image;
    }
}

if(!function_exists('numToChinese')) {
    /**
     * 数字转换为中文
     * @param string|integer|float $num 目标数字
     * @param bool $mode 模式[true:金额（默认）,false:普通数字表示]
     * @param bool $sim 使用小写（默认）
     * @return string
     */
    function numToChinese($num = '', bool $mode = false,bool $sim = true){
        if(!is_numeric($num)) return '含有非数字非小数点字符！';
        if ($num<0||$num>=pow(10,16)) return '请输入大于0且小于10的16次方的数字';
        $char = $sim ? array('零','一','二','三','四','五','六','七','八','九') : array('零','壹','贰','叁','肆','伍','陆','柒','捌','玖');
        $unit = $sim ? array('','十','百','千','','万','亿','兆') : array('','拾','佰','仟','','萬','億','兆');
        $return = $mode ? '元':'点';
        //小数部分
        if(strpos($num, '.')){
            list($num,$dec) = explode('.', $num);
            $dec = strval(round($dec,2));
            if($mode){
                $return .= "{$char[$dec[0]]}角{$char[$dec[1]]}分";
            }else{
                for($i = 0,$c = strlen($dec);$i < $c;$i++) {
                    $return .= $char[$dec[$i]];
                }
            }
        }
        $out = array();
        //整数部分
        $str = $mode ? strrev(intval($num)) : strrev($num);
        for($i = 0,$c = strlen($str);$i < $c;$i++) {
            $out[$i] = $char[$str[$i]];
            if($mode){
                $out[$i] .= $str[$i] != '0'? $unit[$i%4] : '';
                if($i>1 and $str[$i]+$str[$i-1] == 0){
                    $out[$i] = '';
                }
                if($i%4 == 0){
                    $out[$i] .= $unit[4+floor($i/4)];
                }
            }
        }
        $return = join('',array_reverse($out)) . $return;
        return $return;
    }
}

if (!function_exists('getDistance')) {
    /**
     * 计算两点之间的距离
     * @param float $lng1 经度1
     * @param float $lat1 纬度1
     * @param float $lng2 经度2
     * @param float $lat2 纬度2
     * @param int $unit m，km
     * @param int $decimal 位数
     * @return float
     */
    function getDistance(float $lng1, float $lat1, float $lng2, float $lat2, int $unit = 2, int $decimal = 2)
    {
        $EARTH_RADIUS = 6370.996; // 地球半径系数
        $PI           = 3.1415926535898;
        $radLat1 = $lat1 * $PI / 180.0;
        $radLat2 = $lat2 * $PI / 180.0;
        $radLng1 = $lng1 * $PI / 180.0;
        $radLng2 = $lng2 * $PI / 180.0;
        $a = $radLat1 - $radLat2;
        $b = $radLng1 - $radLng2;
        $distance = 2 * asin(sqrt(pow(sin($a / 2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($b / 2), 2)));
        $distance = $distance * $EARTH_RADIUS * 1000;
        if ($unit === 2) {
            $distance /= 1000;
        }
        return round($distance, $decimal);
    }

}

if (!function_exists('replacePicUrl')) {
    /**
     * 替换富文本中的图片 添加域名
     * @param string $content 要替换的内容
     * @param string $domain 域名地址
     * @return string
     * @eg
     */
    function replacePicUrl(string $content = null,string $domain = '') {
        $domain = $domain?$domain:request()->getSchemeAndHttpHost();
        $url = $domain.'/uploads';
        $pregRule = "/<[img|IMG].*?src=[\'|\"]\/uploads(.*?(?:[\.jpg|\.jpeg|\.png|\.gif|\.bmp]))[\'|\"]/";
        $content = preg_replace($pregRule, '<img src="'.$url.'${1}" style="max-width:100%;display: inline-block;height:auto"', $content);
        $content = preg_replace("/&nbsp;/", '<span style="width:3px;display: inline-block"></span>', $content);
        $content = preg_replace("/\n/", '<br />', $content);
        $content = preg_replace("/\r/", '<br />', $content);
        $content = str_replace('text-indent:32.0pt;','',$content);
        $content = str_replace('mso-char-indent-count:2.0;','',$content);
        $content = str_replace('line-height:28.0pt;','',$content);
        $content = str_replace('mso-line-height-rule:exactly','',$content);
        $content = str_replace('text-indent:32.0pt','',$content);
        $content = str_replace('mso-char-indent-count:2.0','',$content);
        $content = str_replace('line-height:28.0pt','',$content);
        return $content;
    }
}


if (!function_exists('build_order_no')) {
    /**
     * @param int $number
     * @return string
     */
    function build_order_no(int $number = 6){
        @date_default_timezone_set("PRC");
        $order_id_main = date('YmdHis') . Random::numeric($number);
        $order_id_len = strlen($order_id_main);
        $order_id_sum = 0;
        for($i=0; $i<$order_id_len; $i++){
            $order_id_sum += (int)(substr($order_id_main,$i,1));
        }
        return $order_id_main . str_pad((100 - $order_id_sum % 100) % 100,2,'0',STR_PAD_LEFT);
    }
}

if (!function_exists('format_bytes')) {

    /**
     * 将字节转换为可读文本
     * @param int    $size      大小
     * @param string $delimiter 分隔符
     * @return string
     */
    function format_bytes($size, $delimiter = '')
    {
        $units = array('B', 'KB', 'MB', 'GB', 'TB', 'PB');
        for ($i = 0; $size >= 1024 && $i < 6; $i++) {
            $size /= 1024;
        }
        return round($size, 2) . $delimiter . $units[$i];
    }
}

if (!function_exists('datetime')) {

    /**
     * 将时间戳转换为日期时间
     * @param int    $time   时间戳
     * @param string $format 日期时间格式
     * @return string
     */
    function datetime($time, $format = 'Y-m-d H:i:s')
    {
        $time = is_numeric($time) ? $time : strtotime($time);
        return date($format, $time);
    }
}

if (!function_exists('human_date')) {

    /**
     * 获取语义化时间
     * @param int $time  时间
     * @param int $local 本地时间
     * @return string
     */
    function human_date($time, $local = null)
    {
        return Date::human($time, $local);
    }
}

if (!function_exists('is_really_writable')) {
    /**
     * 判断文件或文件夹是否可写
     * @param string $file 文件或目录
     * @return    bool
     */
    function is_really_writable(string $file)
    {
        if (DIRECTORY_SEPARATOR === '/') {
            return is_writable($file);
        }
        if (is_dir($file)) {
            $file = rtrim($file, '/') . '/' . md5(mt_rand());
            if (($fp = @fopen($file, 'ab')) === false) {
                return false;
            }
            fclose($fp);
            @chmod($file, 0777);
            @unlink($file);
            return true;
        } elseif (!is_file($file) or ($fp = @fopen($file, 'ab')) === false) {
            return false;
        }
        fclose($fp);
        return true;
    }
}

if (!function_exists('rm_dirs')) {

    /**
     * 删除文件夹
     * @param string $dirname  目录
     * @param bool   $withself 是否删除自身
     * @return boolean
     */
    function rm_dirs(string $dirname, bool $withself = true)
    {
        if (!is_dir($dirname)) {
            return false;
        }
        $files = new RecursiveIteratorIterator(
            new RecursiveDirectoryIterator($dirname, RecursiveDirectoryIterator::SKIP_DOTS),
            RecursiveIteratorIterator::CHILD_FIRST
        );

        foreach ($files as $fileinfo) {
            $todo = ($fileinfo->isDir() ? 'rmdir' : 'unlink');
            $todo($fileinfo->getRealPath());
        }
        if ($withself) {
            @rmdir($dirname);
        }
        return true;
    }
}

if (!function_exists('copy_dirs')) {
    /**
     * 复制文件夹
     * @param string $source 源文件夹
     * @param string $dest   目标文件夹
     */
    function copy_dirs(string $source, string $dest)
    {
        if (!is_dir($dest)) {
            mkdir($dest, 0755, true);
        }
        foreach (
            $iterator = new RecursiveIteratorIterator(
                new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS),
                RecursiveIteratorIterator::SELF_FIRST
            ) as $item
        ) {
            if ($item->isDir()) {
                $sontDir = $dest . '/' . $iterator->getSubPathName();
                if (!is_dir($sontDir)) {
                    mkdir($sontDir, 0755, true);
                }
            } else {
                copy($item, $dest . '/' . $iterator->getSubPathName());
            }
        }
    }
}

if (!function_exists('letter_avatar')) {
    /**
     * 首字母头像
     * @param string $text
     * @return string
     */
    function letter_avatar(string $text)
    {
        $total = unpack('L', hash('adler32', $text, true))[1];
        $hue = $total % 360;
        list($r, $g, $b) = hsv2rgb($hue / 360, 0.3, 0.9);

        $bg = "rgb({$r},{$g},{$b})";
        $color = "#ffffff";
        $first = mb_strtoupper(mb_substr($text, 0, 1));
        $src = base64_encode('<svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="100" width="100"><rect fill="' . $bg . '" x="0" y="0" width="100" height="100"></rect><text x="50" y="50" font-size="50" text-copy="fast" fill="' . $color . '" text-anchor="middle" text-rights="admin" dominant-baseline="central">' . $first . '</text></svg>');
        return 'data:image/svg+xml;base64,' . $src;
    }
}

if (!function_exists('hsv2rgb')) {
    function hsv2rgb($h, $s, $v)
    {
        $r = $g = $b = 0;
        $i = floor($h * 6);
        $f = $h * 6 - $i;
        $p = $v * (1 - $s);
        $q = $v * (1 - $f * $s);
        $t = $v * (1 - (1 - $f) * $s);
        switch ($i % 6) {
            case 0:
                $r = $v;
                $g = $t;
                $b = $p;
                break;
            case 1:
                $r = $q;
                $g = $v;
                $b = $p;
                break;
            case 2:
                $r = $p;
                $g = $v;
                $b = $t;
                break;
            case 3:
                $r = $p;
                $g = $q;
                $b = $v;
                break;
            case 4:
                $r = $t;
                $g = $p;
                $b = $v;
                break;
            case 5:
                $r = $v;
                $g = $p;
                $b = $q;
                break;
        }
        return [
            floor($r * 255),
            floor($g * 255),
            floor($b * 255)
        ];
    }
}

